<template>
  <view class="profile-container">
    <u-icon
      name="arrow-left"
      class="nav-back"
      size="24"
      bold
      @click="backClick"
    ></u-icon>
    <view id="profile-panel">
      <view class="list">
        <view class="title" style="border-right: 1px solid #e3e3e3">通道</view>
        <view id="profile-channel"></view>
      </view>
      <view class="list">
        <view class="title">电缆段</view>
        <view id="profile-cable-section"></view>
      </view>
    </view>
    <view
      id="pm_map"
      :well-id="wellId"
      :change:well-id="openLayer.handleWellIdChange"
    ></view>
  </view>
</template>

<script>
import _ from 'lodash'

export default {
  data() {
    return {
      wellId: '',
    }
  },
  mounted() {},
  methods: {
    backClick() {
      uni.navigateBack()
    },
  },
  onLoad(options) {
    if (options.id) {
      this.wellId = options.id
    }
  },
  destroyed() {},
}
</script>

<script module="openLayer" lang="renderjs">
import "ol/ol.css";
import "ol-ext/dist/ol-ext.min.css";
import { Map, View } from "ol";
import { Fill, Icon, Stroke, Style } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { defaults as defaultControls } from "ol/control";
import MousePosition from "ol/control/MousePosition";
import { createStringXY } from "ol/coordinate";
import { fireOperate } from "./operate";
import {
  assistStyle,
  dlStyle,
  genStyleFunction,
  kwStyle,
  pmBottomStyle,
  stylePM,
} from "./style";

import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import GridReference from "ol-ext/control/GridReference";
import { defaults as defaultInteractions } from "ol/interaction";
import * as turf from "@turf/turf";
import Select from "ol/interaction/Select";
import _ from "lodash";
import { showMeasurements } from "./measure";

import {
  getCableWellById,
  wellSectionHoleAPI,
} from "./api";
import { fromLonLat } from "ol/proj";


const commonBackgroundImage='linear-gradient(135deg, #fdfcfb 0%, #e2d1c3 100%)'
const highLightBackgroundImage="radial-gradient(circle 248px at center, #16d9e3 0%, #30c7ec 47%, #46aef7 100%)"

class WellProfile {
  constructor(wellId) {
    const initialData = {
      wellId: wellId,
      currentWell: null,
      propPanelData: { name_1: "", name_2: "", images: [] },
      propPanel: "PM",
      initCenter: [118.866766, 32.154609],
      map: null,
      snapInteraction: null,
      undoInteraction: null,
      selectInteraction: null,
      transformInteraction: null,
      rotateInteraction: null,
      modifyInteraction: null,
      mapNotification: null,
      compassLayer: null,
      qtLayer: null,
      pmLayer: null,
      gdkLayer: null,
      kwLayer: null,
      dlLayer: null,
      tzjLayer: null,
      assistLayer: null,
      currentInteraction: null,
      noDrawFunc: function noDraw(e) {
        console.log("no draw", e);
      },
      singleClickFunc: this.noDrawFunc,
      drawpanelVisble: false,
      drawpanelZJVisble: false,
      drawParamVisble: null,
      pmName_feature: null,
      pmName_direction: null,
      pmName_seq: null,
      pmNamePanelVisble: false,
      zhuji_text: "",
      zhuji_feature: null,
      zhujiPanelVisble: false,
      fastDrawData: {},
      drawCircleQT2xRadius: 1000,
      drawRectQThorizontal: 1000,
      drawRectQTvertical: 1000,
      drawRectGDKhorizontal: 1000,
      drawRectGDKvertical: 1000,
      drawPMhorizontal: 1000,
      drawPMvertical: 1000,
      drawPMangle: 0,
      drawGk: { size: 300, material: 1, batch: false },
      drawTZJ: {},
      tdData: [],
      dlAllData: {},
      currentChannel: null,
      dlData: [],
      gkMaterialData: [],
      highlightPM: null,
      highlightCable: null,
      isSelectInteractionActive: false,
      channels:[],
      cableSections:[],
      selectedChannels:new Set(),// 选中的通道ID
      selectedCableSections:new Set() // 选中的电缆段ID
    };

    for (const key in initialData) {
      if (Object.hasOwnProperty.call(initialData, key)) {
        const element = initialData[key];
        this[key] = element;
      }
    }
  }
  async init() {
    const data = await getCableWellById(this.wellId);
    this.currentWell = data.result;
    try {
      if (this.currentWell.geojson.geometry.coordinates.length === 2) {
        this.initCenter = fromLonLat(
          this.currentWell.geojson.geometry.coordinates
        );

        this.dlAllData = {};
        this.dlData = [];
        const {allData, channels, cableSections,wellSectionContent}=this.currentWell
        this.dlAllData = allData
        this.channels=channels
        this.cableSections=cableSections
        const channelListViewHtml=channels.map(i=>`<div id="channel-${i.id}" class="cell" style="background-image:${commonBackgroundImage}">${i.name}</div>`).join('')

        const cableSectionDom=document.getElementById("profile-cable-section")
        const channelDom=document.getElementById("profile-channel")

        channelDom.innerHTML=channelListViewHtml

        cableSectionDom.addEventListener('click',e=>{
          console.log("selected features:",this.selectInteraction.features_.array_)
          this.clearCableSectionInMap()
          e.target.style.backgroundImage=highLightBackgroundImage
          const cableId=e.target.id.split('-')[1]
          this.selectedCableSections.add(cableId)
          this.cableClick(cableId)
          // 点击电缆段时保持通道的高亮状态
        })

        channelDom.addEventListener('click',e=>{
          this.clearFeatureSelection()
          e.target.style.backgroundImage=highLightBackgroundImage
          const channelId=e.target.id.split('-')[1]
          this.selectedChannels.add(channelId)
          this.channelClick(channelId, true)
        })

        let data = wellSectionHoleAPI.enums;
        this.gkMaterialData = data.result.holeMaterial;
      }
      if (this.channels !== undefined && this.channels.length > 0)
          setTimeout(() => this.channelClick(this.channels[0].id, false), 300)

    } catch (ignored) {
      console.error(ignored);
      // this.$message.error("请先填写电缆井必要属性");
      return;
    }

    // reset map
    if (this.map !== null) {
      this.reset();
    }
    // init map
    else {
      this.addCompass();

      this.qtLayer = new VectorLayer({
        source: new VectorSource(),
        style: genStyleFunction(
          (isSelected) => [
            new Style({
              fill: new Fill({
                color: "rgba(255, 204, 51, 0.2)",
              }),
              stroke: new Stroke({
                color: isSelected ? "rgb(66, 173, 222)" : "rgb(255, 204, 51)",
                width: isSelected ? 5 : 1,
              }),
            }),
          ],
          [showMeasurements],
          this
        ),
      });

      this.gdkLayer = new VectorLayer({
        source: new VectorSource(),
        style: genStyleFunction(
          (isSelected) => [
            new Style({
              fill: new Fill({
                color: "rgba(220,238,185, 0.2)",
              }),
              stroke: new Stroke({
                color: isSelected ? "rgb(66, 173, 222)" : "rgb(220,238,185)",
                width: isSelected ? 5 : 1,
              }),
            }),
          ],
          [showMeasurements],
          this
        ),
      });

      this.pmLayer = new VectorLayer({
        source: new VectorSource(),
        style: (f) =>
          genStyleFunction(
            null,
            [stylePM, showMeasurements, pmBottomStyle],
            this
          )(f),
      });

      this.tzjLayer = new VectorLayer({
        source: new VectorSource(),
        style: genStyleFunction(
          (isSelected) => [
            new Style({
              stroke: new Stroke({
                color: isSelected ? "rgb(66, 173, 222)" : "rgb(0, 50, 0)",
                width: isSelected ? 5 : 1,
              }),
            }),
          ],
          [],
          this
        ),
      });

      this.kwLayer = new VectorLayer({
        source: new VectorSource(),
        style: (f) => genStyleFunction(null, [kwStyle], this)(f),
      });

      this.dlLayer = new VectorLayer({
        source: new VectorSource(),
        style: (f) => genStyleFunction(null, [dlStyle], this)(f),
      });

      this.assistLayer = new VectorLayer({
        source: new VectorSource(),
        style: (f) => genStyleFunction(null, [assistStyle], this)(f),
      });

      this.map = new Map({
        target: "pm_map",
        interactions: defaultInteractions({ doubleClickZoom: false }),
        controls: defaultControls({
          attribution: false,
          rotate: false,
          zoom: false,
        }),
        layers: [
          this.compassLayer,
          this.qtLayer,
          this.pmLayer,
          this.tzjLayer,
          this.gdkLayer,
          this.kwLayer,
          this.dlLayer,
          this.assistLayer,
        ],
      });

      this.selectInteraction = new Select({ hitTolerance: 2, style: null });
      this.selectInteraction.on("select", (e) => {
        this.map.getLayers().forEach((l) => l.getSource().changed());

        const selectedFeature = e.selected[0];
        if(_.isEmpty(selectedFeature)){
          return
        }
        const connects = selectedFeature.get("connect");
        const dbids=selectedFeature.get('dbid')

        setTimeout(() => {
          if(connects){
            console.log('this.channels:',this.channels)
            const channelIds=this.channels.map(i=>i.id)
            channelIds.forEach(channelId=>{
              if(connects.indexOf(channelId)>-1){
                this.selectedChannels.add(channelId)
                this.channelClick(channelId, true)
                setTimeout(() => (this.dlData = this.dlAllData[channelId]), 100);
              }
            })
          }

          if(dbids){
            console.log('this.cableSections:',this.cableSections)
            _.forEach(this.cableSections,item=>{
              const {id}=item
              if(dbids.indexOf(id)>-1){
                this.selectedCableSections.add(id)
                document.getElementById("cableSection-"+id).style.backgroundImage=highLightBackgroundImage
              }
            })
          }
        }, 100);
      });
      this.map.addInteraction(this.selectInteraction);

      this.map.on("singleclick", (e) => {
        this.singleClickFunc(e)
        this.clearFeatureSelection()
      });
      this.addGrid();
    }

    this.map.setView(
      new View({
        center: this.initCenter,
        projection: "EPSG:3857",
        maxZoom: 25,
        minZoom: 21,
        zoom: 22,
        enableRotation: false //禁止旋转
      })
    );

    if (this.currentWell.wellSectionContent !== null) {

      fireOperate("Read", this, this.currentWell.wellSectionContent);
    }

    this.singleClickFunc = this.noDrawFunc;
  }
  clearFeatureSelection() {
    this.selectedChannels.forEach(id=>{
      document.getElementById("channel-"+id).style.backgroundImage=commonBackgroundImage
    })
    this.selectedChannels.clear()
    this.selectedCableSections.forEach(id=>{
      document.getElementById("cableSection-"+id).style.backgroundImage=commonBackgroundImage
    })
    this.selectedCableSections.clear()
    // 清除掉高亮的图形
    this.highlightPM = null;
    this.highlightCable = null;
    // 清除掉选中的feature
    this.selectInteraction.features_.array_=[]
    this.map.getLayers().forEach((l) => l.getSource().changed());
  }
  clearCableSectionInMap(){
    this.selectedCableSections.forEach(id=>{
      document.getElementById("cableSection-"+id).style.backgroundImage=commonBackgroundImage
    })
    this.selectedCableSections.clear()
    this.highlightCable = null;
  }
  reset() {
    this.cancelDraw();
    this.map.getLayers().forEach((l) => l.getSource().clear(false));
    this.addCompass();
    this.map.getControls().forEach((c) => {
      if (c instanceof GridReference) this.map.removeControl(c);
    });
    this.addGrid();
    this.drawpanelVisble = false;
    this.drawpanelZJVisble = false;
    this.fastDrawGK = {};
    this.fastDrawData = {};
    this.currentChannel = null;
  }
  addCompass() {
    if (this.compassLayer === null) {
      this.compassLayer = new VectorLayer({
        source: new VectorSource({
          features: [
            new Feature({
              geometry: new Point(this.initCenter),
            }),
          ],
        }),
        style: new Style({
          image: new Icon({
            scale: 0.2,
            src: "http://p0.qhimg.com/t01d69e6f241e09de33.png",
          }),
        }),
      });
    } else {
      this.compassLayer.getSource().addFeature(
        new Feature({
          geometry: new Point(this.initCenter),
        })
      );
    }
  }
  addGrid() {}
  updateSize() {
    this.map.updateSize();
  }
  goToGJT() {
    this.$emit("switchMode", { mode: "gjt" });
  }
  isDlInPm(cable, pm) {
    return (
      this.dlLayer
        .getSource()
        .getFeatures()
        .filter((dl) => {
          if (dl.get("dbid") && dl.get("dbid") === cable.id) {
            if (
              turf.booleanContains(
                turf.toWgs84(turf.polygon(pm.getGeometry().getCoordinates())),
                turf.toWgs84(turf.point(dl.getGeometry().getCoordinates()))
              )
            ) {
              return true;
            }
          }
        }).length !== 0
    );
  }
  addDL(e, pmId) {
    const ops = e.key.split("-");
    if (ops[0] === "add") {
      // fireDraw(mapping[ops[2]], this, { id: ops[1], pm: pmId });
    } else if (ops[0] === "remove") {
      this.dlLayer
        .getSource()
        .getFeatures()
        .filter(
          (f) =>
            f.get("dbid") === ops[1] &&
            this.pmLayer
              .getSource()
              .getFeatures()
              .filter(
                (pm) =>
                  pm.getId() === pmId &&
                  pm
                    .getGeometry()
                    .intersectsCoordinate(f.getGeometry().getCoordinates())
              ).length !== 0
        )
        .forEach((f) => this.dlLayer.getSource().removeFeature(f));
    }
    this.$refs["dlList"].$forceUpdate();
  }
  connectPM(e) {
    const ops = e.key.split("-");
    if (ops[0] === "connect") {
      if (
        this.selectInteraction.getFeatures().getLength() === 1 &&
        this.selectInteraction
          .getFeatures()
          .getArray()[0]
          .getId()
          .startsWith("PM-")
      ) {
        this.pmLayer
          .getSource()
          .getFeatures()
          .filter(
            (f) =>
              f.get("connect") !== undefined &&
              f.get("connect").includes(ops[1])
          )
          .map((f) => _.remove(f.get("connect"), (n) => n === ops[1]));
        const f = this.selectInteraction.getFeatures().getArray()[0];
        if (f.get("connect") === undefined) f.set("connect", [ops[1]]);
        else f.get("connect").push(ops[1]);
      } else {
        console.log("请先选择所需关联的剖面");
      }
    } else if (ops[0] === "disconnect") {
      this.pmLayer
        .getSource()
        .getFeatures()
        .filter(
          (f) =>
            f.get("connect") !== undefined && f.get("connect").includes(ops[1])
        )
        .map((f) => {
          this.dlAllData[ops[1]].forEach((dl) =>
            this.addDL({ key: "remove-" + dl.id }, f.getId())
          );
          _.remove(f.get("connect"), (n) => n === ops[1]);
        });
    }
    this.$refs["channelList"].$forceUpdate();
    this.channelClick(ops[1], false);
  }

  changePMname() {
    if (
      this.pmName_feature !== null &&
      this.pmName_direction !== null &&
      this.pmName_seq !== null
    ) {
      this.pmName_feature.set("name", this.pmName_direction + this.pmName_seq);
      this.pmName_feature = this.pmName_direction = this.pmName_seq = null;
    }
    this.pmNamePanelVisble = false;
  }
  changeZHUJItext(e) {
    if (
      this.zhuji_feature !== null &&
      this.zhuji_text !== null &&
      this.zhuji_text !== ""
    ) {
      this.zhuji_feature = this.assistLayer
        .getSource()
        .getFeatures()
        .filter((f) => f.getId() === this.zhuji_feature.getId())[0];
      this.zhuji_feature.set("text", this.zhuji_text);
      this.zhuji_feature = null;
      this.zhuji_text = "";
    }
    this.zhujiPanelVisble = false;
  }

  operateClick(type, param) {
    const types = ["Select", "Transform", "Modify"];
    if (types.includes(type)) {
      types
        .filter((t) => t !== type)
        .map((t) => this[t.toLowerCase() + "Interaction"].setActive(false));
    }
    fireOperate(type, this, param);
  }
  async channelClick(channelId, needHighlight = true) {
    if (needHighlight) {
      this.highlightPM = channelId;
      this.pmLayer.getSource().changed();
      const element=document.getElementById("channel-"+channelId)
      element.style.backgroundImage=highLightBackgroundImage
    }
    this.currentChannel = channelId;
    this.dlData = [];
    const cableSectionDom=document.getElementById("profile-cable-section")
    const cables=this.dlAllData[channelId]
    const cableSectionListViewHtml=_.map(cables, i=>{
          return `<div id="cableSection-${i.id}" class="cell" style="background-image:${commonBackgroundImage}">${i.name}</div>`
        }).join('')
    // 只显示当前通道下的电缆段
    cableSectionDom.innerHTML=cableSectionListViewHtml
    setTimeout(() => (this.dlData = this.dlAllData[channelId]), 100);
  }
  cableClick(cableId) {
    this.highlightCable = cableId;
    this.dlLayer.getSource().changed();
  }
}

// 小新河路北043
export default {
  name: "app",
  data() {
    return {};
  },
  mounted() {

  },
  methods: {
    handleWellIdChange(newValue){
      const wellProfile = new WellProfile(newValue);
      wellProfile.init();
    }
  },

};
</script>

<style>
.profile-container {
  height: 100vh;
  width: 100vw;
  position: relative;
}

.nav-back {
  position: absolute;
  top: 4vh;
  left: 4vw;
  background-color: #ffffff;
  padding: 0.2rem;
  border-radius: 0.5rem;
  margin-right: 1rem;
  z-index: 10;
}

#pm_map {
  width: 100vw;
  height: 100vh;
  background-color: rgba(199, 237, 204, 0.3);
}

#profile-panel {
  display: flex;
  position: absolute;
  height: 30vh;
  width: 100%;
  overflow: auto;
  bottom: 0;
  z-index: 10;
  background: #ffffff;
}

#profile-panel .list {
  width: 50%;
}

#profile-panel .title {
  text-align: center;
  padding: 0.5rem;
  border-bottom: 1px solid #e3e3e3;
}

#profile-panel .cell {
  padding: 0.5rem 0.2rem;
  border: 1px solid #e3e3e3;
}
</style>
